package com.itlong.cloud.intercept;


import com.itlong.cloud.POJO.PO.OperationLogPO;
import com.itlong.cloud.POJO.PO.UserLoginLogPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.property.PropertyUserCacheVO;
import com.itlong.cloud.POJO.VO.property.PropertyUserLoginCheckVO;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.SystemTypeEnum;
import com.itlong.cloud.noncore.commons.IOperationLogServiceClient;
import com.itlong.cloud.noncore.commons.IUserLoginLogServiceClient;
import com.itlong.cloud.user.property.IPropertyUserServiceClient;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * <desc>
 *      物业系统日志记录器。
 * </desc>
 *
 * @createDate 2017/08/29
 */
@Aspect
@Component
public class LoggerInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerInterceptor.class);

    // 定义一个切入点
    @Pointcut("execution(* com.itlong.cloud.controller..*.*(..))")
    public void excudeService(){}

    @Autowired
    IOperationLogServiceClient iOperationLogServiceClient;

    @Autowired
    IUserLoginLogServiceClient iUserLoginLogServiceClient;

    @Autowired
    IPropertyUserServiceClient iPropertyUserServiceClient;

    /**
     * <desc>
     *      用户操作日志证拦截器
     *      注：每个系统的操作日志拦截器需在拦截器中指定SystemType 对应枚举类 SystemTypeEnum
     * </desc>
     *
     * @param thisJoinPoint
     * @return
     * @author Jiaqi.X
     * @createDate 2017/10/16
     */
    @Around("excudeService() && @annotation(loggerInfo)")
    public Object twiceAsOld(ProceedingJoinPoint thisJoinPoint,LoggerInfo loggerInfo) throws Throwable {
        Object result = thisJoinPoint.proceed();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String uri = request.getRequestURI();
        String ip = HttpProtocolUtil.getIpAddr(request);
        //使用正则表达式校验IP的格式是否正确
        String pattern="^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."+"(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
        boolean isMatch= Pattern.matches(pattern, ip);
        ip = isMatch?ip:"";
        if ("login".equals(loggerInfo.identifer())) {
            // 用户为登录操作，保存用户登录操作日志
            UserLoginLogPO userLoginLogPO = new UserLoginLogPO();
            PropertyUserLoginCheckVO loginUser = (PropertyUserLoginCheckVO)request.getAttribute("loginUser");
            if (loginUser != null && StringUtils.isNotBlank(loginUser.getToken())){
//                PropertyUserCacheVO cacheUser = iPropertyUserServiceClient.checkCacheUser(loginUser.getLoginUserId(), loginUser.getToken());
                userLoginLogPO.setAccount(loginUser.getUserName());
                userLoginLogPO.setRealName(loginUser.getRealName());
                userLoginLogPO.setIp(ip);
                userLoginLogPO.setSystemType(SystemTypeEnum.PROPERTY.getType());
                userLoginLogPO.setDescription(request.getAttribute("checkMessage").toString());
            } else {
                userLoginLogPO.setAccount(request.getParameter("account"));
                if (userLoginLogPO.getAccount() == null) {
                    userLoginLogPO.setAccount(request.getAttribute("account") == null ? null : request.getAttribute("account").toString());
                }
                userLoginLogPO.setIp(ip);
                userLoginLogPO.setSystemType(SystemTypeEnum.PROPERTY.getType());
                userLoginLogPO.setDescription(request.getAttribute("checkMessage").toString());
            }
            iUserLoginLogServiceClient.save(userLoginLogPO);
        } else {
            // 用户为其它操作，保存用户其它操作日志
//            MethodSignature signature = (MethodSignature) thisJoinPoint.getSignature();
//            Method method=signature.getMethod();
            MessageVO messageVO = (MessageVO)result;
            Map<String,Object> map = StringUtils.isNotBlank(messageVO.getExtend()) ? JsonUtil.toObject(messageVO.getExtend(), HashMap.class) : null;
            String dataId = map != null ? StringHandlerUtil.getNullOrStringForObject(map.get("dataId")) : null;
            OperationLogPO log = new OperationLogPO();
            String token = request.getParameter("token");
            if (token == null) {
                token = request.getAttribute("token") == null ? null : request.getAttribute("token").toString();
            }
            String loginUserId = request.getParameter("loginUserId");
            if (loginUserId == null) {
                loginUserId = request.getAttribute("loginUserId") == null ? null : request.getAttribute("loginUserId").toString();
            }
            //获取登录用户信息
            if (StringUtils.isNotEmpty(loginUserId) && StringUtils.isNotEmpty(token)) {
                PropertyUserCacheVO cacheUser = iPropertyUserServiceClient.checkCacheUser(loginUserId, token);
                if (cacheUser != null && (StringUtils.isNotBlank(cacheUser.getUserName()) || LogDescConstant.USER_PROPERTY_LOGOUT_LOG_DESC.equals(loggerInfo.operateDesc()))) {
                    log.setAccount(cacheUser.getUserName());
                    log.setRealName(cacheUser.getRealName());
                    log.setIp(ip);
                    log.setSystemType(SystemTypeEnum.PROPERTY.getType());
                    log.setOperationUse(loggerInfo.operateDesc());
                    log.setUrl(uri);
                    log.setDataId(dataId);
                    //保存操作记录
                    iOperationLogServiceClient.save(log);
                }
            } else {
                // 未登录的情况有用户找回密码时的校验验证码和修改密码操作，记录，dataId为userName
                log.setAccount(dataId);
                log.setIp(ip);
                log.setSystemType(SystemTypeEnum.PROPERTY.getType());
                log.setOperationUse(loggerInfo.operateDesc());
                log.setUrl(uri);
                log.setDataId(dataId);
                //保存操作记录
                iOperationLogServiceClient.save(log);
            }
        }
        return result;
    }
}
